import process from "process";
import * as outputs from '../outputs'
import logging from '../logging'
import {uploadReport} from '../testCase/uploadReport'
import {generateReadlineResults} from './util'

const url = 'http://testing.rdc.aliyun.com/assets'

export interface CheckRedline {
    key: string;
    type: string;
    threshold: number;
}

export const Error = "Error"
export const Warning = "Warning"

export interface RedlineInfo {
    title: string,
    reportUrl: string,
    readlineResults: RedlineResult[]
}

export interface RedlineResult {
    key: string;
    title: string;
    style: string;
    value: number;
}

export interface CodeScanResult {
    reportLocalPath: string;
    issue: Issue | undefined;
}

export interface Issue {
    total: number;
    blocker:number;
    critical: number;
    major:number;
}

export function redlineCheckResult(redlines: CheckRedline[], key: string, value: number): boolean {
    const redline = redlines.find(rl => rl.key === key);

    // 如果没有找到相应的检查红线配置，则退出函数
    if (!redline) return true;

    const {type, threshold} = redline;

    // 当 threshold 为字符串时，必须为数字字符串
    if (isNaN(Number(threshold))) {
        logging.error(`skip check redline key ${redline.key}, threshold ${threshold} must be a number or number string`);
        return false
    }

    let checkResult: boolean;
    switch (type) {
        case 'ge': // 大于等于
        case 'GE': // 大于等于
            checkResult = value >= threshold;
            break;
        case 'eq': // 等于
        case 'EQ': // 等于
            checkResult = value === threshold;
            break;
        case 'le': // 小于等于
        case 'LE': // 小于等于
            checkResult = value <= threshold;
            break;
        default: // 如果 type 不匹配，退出函数
            logging.info("check type not matched "+type);
            return false;
    }

    // 如果检查结果为false，输出相关信息
    const output = `[${process.env['stepIdentifier']}]REDLINE_ITEM_LINE:{"key":"${key}","threshold":${threshold},"checkVal":${value},"type":"${type}","checked":true,"checkResult":${checkResult}}`
    logging.info(output);
    outputs.addOutput(output)
    return checkResult;

}



export async function outputCodeScanResult(codeScanResult: CodeScanResult, checkRedlines: string | undefined) {
    const objectKey = await uploadReport(codeScanResult.reportLocalPath)
    const redlineResults = generateReadlineResults(codeScanResult)

    const redlineInfo = {
        title: process.env['name'],
        reportUrl:`${url}/${objectKey}`,
        readlineResults: redlineResults
    } as RedlineInfo
    redlineCheck(redlineInfo, checkRedlines)
}


export function redlineCheck(redlineInfo: RedlineInfo, checkRedlines: string | undefined): boolean {
    title(redlineInfo.title)
    if (redlineInfo.reportUrl) {
        reportResultUrl(redlineInfo.reportUrl)
    }

    let checkResult = true;
    for (const redline of redlineInfo.readlineResults) {
        const outputName = `[${process.env['stepIdentifier']}]STAT_NAME_${redline.key}:${redline.title}`;
        outputs.addOutput(outputName)
        logging.info(outputName)
        const outputValue = `[${process.env['stepIdentifier']}]STAT_VALUE_${redline.key}:${redline.value}`;
        outputs.addOutput(outputValue)
        logging.info(outputValue)
        const outputStyle = `[${process.env['stepIdentifier']}]STAT_STYLE_${redline.key}:${redline.style}`;
        outputs.addOutput(outputStyle)
        logging.info(outputStyle)
        if (checkRedlines) {
            if (!redlineCheckResult(JSON.parse(checkRedlines) as CheckRedline[], redline.key, redline.value)){
                checkResult = false;
            }
        }
    }

    return checkResult;
}

function reportResultUrl(reportUrl: string): void {
    const outputReport = `[${process.env['stepIdentifier']}]STAT_URL__REPORT:${reportUrl}`;
    logging.info(outputReport)
    outputs.addOutput(outputReport)
}


function title(title: string): void {
    const outputTitle = `[${process.env['stepIdentifier']}]STAT_INFO_TITLE:${title}`;
    outputs.addOutput(outputTitle)
    logging.info(outputTitle)
}
